<template>
  <div class="fruit-ninja-container">
    <div class="game-wrapper">
      <!-- 游戏主画布 -->
      <div class="game-area">
        <canvas ref="gameCanvas" 
                class="game-canvas"
                @mousemove="handleMouseMove"
                @mousedown="handleMouseDown"
                @mouseup="handleMouseUp"
                @touchstart="handleTouchStart"
                @touchmove="handleTouchMove"
                @touchend="handleTouchEnd">
        </canvas>

        <!-- 游戏状态显示 -->
        <div class="game-status" :class="{ 'danger': missedFruits >= 2 }">
          <div class="status-item">
            <span class="status-value">{{ score }}</span>
            <span class="status-label">分数</span>
          </div>
          <div class="status-item">
            <span class="status-value">{{ combo }}x</span>
            <span class="status-label">连击</span>
          </div>
          <div class="missed-fruits">
            <span v-for="i in 3" :key="i" 
                  class="fruit-indicator"
                  :class="{ 'missed': i <= missedFruits }">
              🍎
            </span>
          </div>
        </div>

        <!-- 游戏结束界面 -->
        <div v-if="gameOver" class="game-over">
          <div class="game-over-content">
            <h2>游戏结束</h2>
            <div class="score-board">
              <div class="score-item">
                <span class="label">最终得分</span>
                <span class="value">{{ score }}</span>
              </div>
              <div class="score-item">
                <span class="label">最大连击</span>
                <span class="value">{{ maxCombo }}x</span>
              </div>
              <div class="score-item">
                <span class="label">最高记录</span>
                <span class="value">{{ highScore }}</span>
              </div>
            </div>
            <button class="restart-button" @click="restartGame">再来一局</button>
          </div>
        </div>
      </div>

      <!-- 游戏控制面板 -->
      <div class="control-panel">
        <div class="button-group">
          <button class="control-button primary" @click="startGame" :disabled="isPlaying">
            开始游戏
          </button>
          <button class="control-button" @click="pauseGame" :disabled="!isPlaying || gameOver">
            {{ isPaused ? '继续' : '暂停' }}
          </button>
        </div>

        <div class="game-instructions">
          <h3>游戏说明</h3>
          <ul>
            <li>用鼠标或手指划过水果可以切开它们</li>
            <li>连续切中水果可以获得连击加成</li>
            <li>切到炸弹会扣分并结束连击</li>
            <li>错过3个水果游戏结束</li>
          </ul>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'

// 游戏配置
const CANVAS_WIDTH = 800
const CANVAS_HEIGHT = 600
const GRAVITY = 0.5
const FRUIT_TYPES = [
  { name: 'apple', color: '#ef4444', radius: 30, points: 10 },
  { name: 'orange', color: '#f97316', radius: 35, points: 15 },
  { name: 'watermelon', color: '#22c55e', radius: 45, points: 20 },
  { name: 'banana', color: '#eab308', radius: 40, points: 25 },
  { name: 'bomb', color: '#000000', radius: 30, points: -50 }
]

// 游戏状态
const score = ref(0)
const highScore = ref(0)
const combo = ref(0)
const maxCombo = ref(0)
const missedFruits = ref(0)
const isPlaying = ref(false)
const isPaused = ref(false)
const gameOver = ref(false)

// 游戏对象
const fruits = ref([])
const slices = ref([])
const particles = ref([])
const blade = ref({ points: [], active: false })

// Canvas相关
const gameCanvas = ref(null)
let ctx = null
let gameLoop = null
let spawnLoop = null

// 添加切片效果配置
const SLICE_DURATION = 500 // 切片效果持续时间（毫秒）
const SLICE_FADE_DURATION = 300 // 切片淡出时间（毫秒）

// 添加爆炸效果
const createExplosion = (x, y) => {
  const particleCount = 20
  for (let i = 0; i < particleCount; i++) {
    const angle = (Math.PI * 2 * i) / particleCount
    const speed = Math.random() * 4 + 2
    particles.value.push({
      x,
      y,
      velocityX: Math.cos(angle) * speed,
      velocityY: Math.sin(angle) * speed,
      size: Math.random() * 3 + 1,
      color: '#ef4444',
      alpha: 1,
      time: Date.now()
    })
  }
}

// 初始化游戏
const initGame = () => {
  const canvas = gameCanvas.value
  canvas.width = CANVAS_WIDTH
  canvas.height = CANVAS_HEIGHT
  ctx = canvas.getContext('2d')

  // 重置游戏状态
  score.value = 0
  combo.value = 0
  maxCombo.value = 0
  missedFruits.value = 0
  fruits.value = []
  slices.value = []
  particles.value = []
  gameOver.value = false
}

// 生成水果
const spawnFruit = () => {
  if (!isPlaying.value || isPaused.value) return

  const type = FRUIT_TYPES[Math.floor(Math.random() * FRUIT_TYPES.length)]
  const x = Math.random() * (CANVAS_WIDTH - 100) + 50
  const speed = Math.random() * 3 + 10
  const angle = Math.random() * Math.PI / 4 + Math.PI / 3

  fruits.value.push({
    type,
    x,
    y: CANVAS_HEIGHT + 50,
    velocityX: Math.cos(angle) * speed,
    velocityY: -Math.sin(angle) * speed,
    rotation: 0,
    rotationSpeed: (Math.random() - 0.5) * 0.2,
    sliced: false
  })
}

// 处理切水果
const checkSlice = (x, y) => {
  fruits.value.forEach(fruit => {
    if (!fruit.sliced) {
      const dx = x - fruit.x
      const dy = y - fruit.y
      const distance = Math.sqrt(dx * dx + dy * dy)
      
      if (distance < fruit.type.radius) {
        // 计算切割角度
        const angle = Math.atan2(dy, dx)
        
        // 标记水果为已切割状态
        fruit.sliced = true
        fruit.sliceAngle = angle
        fruit.sliceTime = Date.now()
        
        // 创建两个切片
        fruit.pieces = [
          {
            x: fruit.x,
            y: fruit.y,
            velocityX: fruit.velocityX - Math.cos(angle) * 2,
            velocityY: fruit.velocityY - Math.sin(angle) * 2,
            rotation: fruit.rotation,
            rotationSpeed: (Math.random() - 0.5) * 0.4
          },
          {
            x: fruit.x,
            y: fruit.y,
            velocityX: fruit.velocityX + Math.cos(angle) * 2,
            velocityY: fruit.velocityY + Math.sin(angle) * 2,
            rotation: fruit.rotation,
            rotationSpeed: (Math.random() - 0.5) * 0.4
          }
        ]

        // 添加切割效果
        slices.value.push({
          start: { x: x - Math.cos(angle) * 50, y: y - Math.sin(angle) * 50 },
          end: { x: x + Math.cos(angle) * 50, y: y + Math.sin(angle) * 50 },
          alpha: 1,
          time: Date.now()
        })

        // 更新分数和连击
        if (fruit.type.name === 'bomb') {
          score.value = Math.max(0, score.value + fruit.type.points)
          combo.value = 0
          // 添加爆炸效果
          createExplosion(fruit.x, fruit.y)
        } else {
          score.value += fruit.type.points * (1 + combo.value * 0.1)
          combo.value++
          maxCombo.value = Math.max(maxCombo.value, combo.value)
          // 添加果汁效果
          createJuiceSplash(fruit.x, fruit.y, fruit.type.color)
        }
      }
    }
  })
}

// 创建果汁飞溅效果
const createJuiceSplash = (x, y, color) => {
  const particleCount = 8
  for (let i = 0; i < particleCount; i++) {
    const angle = (Math.PI * 2 * i) / particleCount
    const speed = Math.random() * 2 + 2
    particles.value.push({
      x,
      y,
      velocityX: Math.cos(angle) * speed,
      velocityY: Math.sin(angle) * speed,
      size: Math.random() * 4 + 2,
      color,
      alpha: 1,
      time: Date.now()
    })
  }
}

// 更新游戏状态
const updateGame = () => {
  if (!isPlaying.value || isPaused.value) return

  // 更新水果位置和状态
  fruits.value.forEach(fruit => {
    if (!fruit.sliced) {
      fruit.x += fruit.velocityX
      fruit.y += fruit.velocityY
      fruit.velocityY += GRAVITY
      fruit.rotation += fruit.rotationSpeed
    } else {
      // 更新切片位置
      fruit.pieces.forEach(piece => {
        piece.x += piece.velocityX
        piece.y += piece.velocityY
        piece.velocityY += GRAVITY * 1.2
        piece.rotation += piece.rotationSpeed
      })
    }
  })

  // 更新粒子效果
  particles.value = particles.value.filter(particle => {
    particle.x += particle.velocityX
    particle.y += particle.velocityY
    particle.velocityY += GRAVITY * 0.5
    particle.alpha = Math.max(0, 1 - (Date.now() - particle.time) / 500)
    return particle.alpha > 0
  })

  // 移除超出屏幕的水果
  fruits.value = fruits.value.filter(fruit => {
    if (fruit.y > CANVAS_HEIGHT + 100 && !fruit.sliced) {
      if (fruit.type.name !== 'bomb') {
        missedFruits.value++
        combo.value = 0
        if (missedFruits.value >= 3) {
          endGame()
        }
      }
      return false
    }
    return fruit.y <= CANVAS_HEIGHT + 100
  })

  // 更新切片效果
  slices.value = slices.value.filter(slice => {
    slice.alpha -= 0.02
    return slice.alpha > 0
  })

  renderGame()
}

// 渲染游戏画面
const renderGame = () => {
  ctx.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT)

  // 渲染粒子
  particles.value.forEach(particle => {
    ctx.beginPath()
    ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2)
    ctx.fillStyle = `${particle.color}${Math.floor(particle.alpha * 255).toString(16).padStart(2, '0')}`
    ctx.fill()
  })

  // 渲染水果
  fruits.value.forEach(fruit => {
    if (!fruit.sliced) {
      // 渲染完整水果
      ctx.save()
      ctx.translate(fruit.x, fruit.y)
      ctx.rotate(fruit.rotation)
      
      ctx.beginPath()
      ctx.arc(0, 0, fruit.type.radius, 0, Math.PI * 2)
      ctx.fillStyle = fruit.type.color
      ctx.fill()
      
      ctx.restore()
    } else {
      // 渲染切开的水果
      fruit.pieces.forEach((piece, index) => {
        ctx.save()
        ctx.translate(piece.x, piece.y)
        ctx.rotate(piece.rotation)
        
        ctx.beginPath()
        ctx.arc(0, 0, fruit.type.radius, index * Math.PI, (index + 1) * Math.PI)
        ctx.lineTo(0, 0)
        ctx.fillStyle = fruit.type.color
        ctx.fill()
        
        // 添加切面效果
        ctx.beginPath()
        ctx.moveTo(-fruit.type.radius, 0)
        ctx.lineTo(fruit.type.radius, 0)
        ctx.strokeStyle = '#ffffff'
        ctx.lineWidth = 2
        ctx.stroke()
        
        ctx.restore()
      })
    }
  })

  // 渲染切片效果
  slices.value.forEach(slice => {
    const gradient = ctx.createLinearGradient(
      slice.start.x, slice.start.y,
      slice.end.x, slice.end.y
    )
    gradient.addColorStop(0, `rgba(255, 255, 255, 0)`)
    gradient.addColorStop(0.5, `rgba(255, 255, 255, ${slice.alpha})`)
    gradient.addColorStop(1, `rgba(255, 255, 255, 0)`)

    ctx.beginPath()
    ctx.moveTo(slice.start.x, slice.start.y)
    ctx.lineTo(slice.end.x, slice.end.y)
    ctx.strokeStyle = gradient
    ctx.lineWidth = 3
    ctx.stroke()
  })

  // 渲染刀光
  if (blade.value.active && blade.value.points.length > 1) {
    ctx.beginPath()
    ctx.moveTo(blade.value.points[0].x, blade.value.points[0].y)
    blade.value.points.forEach(point => {
      ctx.lineTo(point.x, point.y)
    })
    ctx.strokeStyle = '#ffffff'
    ctx.lineWidth = 3
    ctx.stroke()
  }
}

// 鼠标/触摸事件处理
const handleMouseMove = (event) => {
  if (!isPlaying.value || isPaused.value) return
  
  const rect = gameCanvas.value.getBoundingClientRect()
  const x = event.clientX - rect.left
  const y = event.clientY - rect.top

  if (blade.value.active) {
    blade.value.points.push({ x, y })
    if (blade.value.points.length > 10) {
      blade.value.points.shift()
    }
    checkSlice(x, y)
  }
}

const handleMouseDown = (event) => {
  blade.value.active = true
  blade.value.points = []
}

const handleMouseUp = () => {
  blade.value.active = false
}

// 游戏控制
const startGame = () => {
  if (isPlaying.value) return
  
  initGame()
  isPlaying.value = true
  gameLoop = setInterval(updateGame, 1000 / 60)
  spawnLoop = setInterval(spawnFruit, 1000)
}

const pauseGame = () => {
  isPaused.value = !isPaused.value
}

const endGame = () => {
  isPlaying.value = false
  gameOver.value = true
  clearInterval(gameLoop)
  clearInterval(spawnLoop)
  highScore.value = Math.max(highScore.value, score.value)
}

const restartGame = () => {
  startGame()
}

// 生命周期钩子
onMounted(() => {
  initGame()
  window.addEventListener('resize', initGame)
})

onUnmounted(() => {
  clearInterval(gameLoop)
  clearInterval(spawnLoop)
  window.removeEventListener('resize', initGame)
})
</script>

<style scoped>
.fruit-ninja-container {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: var(--theme-bg, #1a1a1a);
  padding: 20px;
}

.game-wrapper {
  display: flex;
  gap: 20px;
  max-width: 1200px;
  width: 100%;
}

.game-area {
  flex: 1;
  position: relative;
  aspect-ratio: 4/3;
  background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
}

.game-canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  cursor: none;
}

.game-status {
  position: absolute;
  top: 20px;
  left: 20px;
  right: 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 20px;
  background: rgba(0, 0, 0, 0.5);
  border-radius: 8px;
  color: white;
  backdrop-filter: blur(4px);
}

.status-item {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.status-value {
  font-size: 24px;
  font-weight: bold;
  color: #60a5fa;
}

.status-label {
  font-size: 14px;
  opacity: 0.8;
}

.missed-fruits {
  display: flex;
  gap: 8px;
}

.fruit-indicator {
  font-size: 20px;
  opacity: 0.5;
  transition: all 0.3s;
}

.fruit-indicator.missed {
  opacity: 1;
  color: #ef4444;
}

.control-panel {
  width: 280px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.button-group {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.control-button {
  padding: 12px;
  border: none;
  border-radius: 8px;
  font-size: 16px;
  cursor: pointer;
  transition: all 0.2s;
  background-color: var(--theme-secondary-bg, #374151);
  color: white;
}

.control-button.primary {
  background-color: var(--theme-primary-color, #3b82f6);
}

.control-button:hover:not(:disabled) {
  transform: translateY(-1px);
  filter: brightness(1.1);
}

.control-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.game-instructions {
  background-color: var(--theme-container-bg, #1f2937);
  padding: 20px;
  border-radius: 8px;
  color: var(--theme-text-color, #e2e8f0);
}

.game-instructions h3 {
  margin: 0 0 12px;
  font-size: 18px;
  color: var(--theme-primary-color, #3b82f6);
}

.game-instructions ul {
  margin: 0;
  padding-left: 20px;
  font-size: 14px;
  line-height: 1.6;
}

.game-over {
  position: absolute;
  inset: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(0, 0, 0, 0.8);
  backdrop-filter: blur(4px);
}

.game-over-content {
  background-color: var(--theme-container-bg, #1f2937);
  padding: 30px;
  border-radius: 12px;
  text-align: center;
  color: white;
}

.score-board {
  margin: 20px 0;
  display: grid;
  gap: 15px;
}

.score-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  background-color: rgba(0, 0, 0, 0.2);
  border-radius: 6px;
}

.score-item .label {
  color: #94a3b8;
}

.score-item .value {
  font-size: 20px;
  font-weight: bold;
  color: #60a5fa;
}

.restart-button {
  padding: 12px 24px;
  background-color: var(--theme-primary-color, #3b82f6);
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 16px;
  cursor: pointer;
  transition: all 0.2s;
}

.restart-button:hover {
  transform: translateY(-1px);
  filter: brightness(1.1);
}

@media (max-width: 768px) {
  .game-wrapper {
    flex-direction: column;
  }

  .control-panel {
    width: 100%;
  }
}

/* 添加切割效果的动画 */
@keyframes slice-fade {
  0% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1.5); }
}

@keyframes piece-rotate {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* 添加粒子动画效果 */
@keyframes particle-fade {
  0% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(0.5); }
}
</style> 